const { ccclass, property } = cc._decorator;

enum MoveType {
    DIRECTION,
    DESTINATION,
}

const _v1 = cc.v2();

@ccclass
export default class Move extends cc.Component {
    static EventType = {
        STOP: "stop"
    }

    private _speed: number = 0;
    get speed(): number {
        return this._speed;
    }
    set speed(value: number) {
        this._speed = value;
    }

    private _direction: cc.Vec2 = cc.Vec2.ZERO;
    private _destination: cc.Vec2 = cc.Vec2.ZERO;
    private _moveType: MoveType = MoveType.DIRECTION;
    private _isStop: boolean = true;

    public moveByDirection(direction: cc.Vec2) {
        this._direction.set(direction);
        this._moveType = MoveType.DIRECTION;
        this._isStop = false;
    }

    public moveToDestination(destination: cc.Vec2) {
        this._destination.set(destination);
        this._moveType = MoveType.DESTINATION;
        this._isStop = false;
    }

    protected update(dt: number): void {
        if (this._isStop) return;
        if (this._moveType === MoveType.DIRECTION) {
            _v1.set(this._direction).mulSelf(dt * this._speed);
            this.node.x += _v1.x;
            this.node.y += _v1.y;
        } else {
            let dist = this.node.getPosition(_v1).subSelf(this._destination).len();
            this.node.getPosition(_v1);
            _v1.lerp(this._destination, Math.min(1, dt * this._speed / dist), _v1);
            this.node.setPosition(_v1);
            if (_v1.fuzzyEquals(this._destination, 0.001)) {
                this.stop();
            }
        }
    }

    stop() {
        this._isStop = true;
        this.node.emit(Move.EventType.STOP);
    }
}
